package com.ruoyi.common.constant;

import com.baomidou.mybatisplus.core.injector.methods.UpdateById;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.common.State;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;

import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 代码生成通用常量
 * 
 * @author ruoyi
 */
public class GenConstants
{
    /** 单表（增删改查） */
    public static final String TPL_CRUD = "crud";

    /** 树表（增删改查） */
    public static final String TPL_TREE = "tree";

    /** 主子表（增删改查） */
    public static final String TPL_SUB = "sub";

    /** 树编码字段 */
    public static final String TREE_CODE = "treeCode";

    /** 树父编码字段 */
    public static final String TREE_PARENT_CODE = "treeParentCode";

    /** 树名称字段 */
    public static final String TREE_NAME = "treeName";

    /** 上级菜单ID字段 */
    public static final String PARENT_MENU_ID = "parentMenuId";

    /** 上级菜单名称字段 */
    public static final String PARENT_MENU_NAME = "parentMenuName";

    /** 主键字段 */
    public static final String ID = "id";
    
    /** 删除标识字段 */
    public static final String DEL_FLAG = "del_flag";

    /** 数据状态标识字段*/
    public static final String STATE = "state";

    /** 排序字段*/
    public static final String WEIGHT = "weight";

    /** 描述字段 */
    public static final String REMARK = "remark";
    
    /** 创建时间*/
    public static final String CREATE_TIME = "create_time";
    
    /** 修改时间*/
    public static final String UPDATE_TIME = "update_time";
    
    /** 创建人员字段*/
    public static final String CREATE_BY = "create_by";

    /** 创建人员字段*/
    public static final String UPDATE_BY = "update_by";

    /** 数据库字符串类型 */
    public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };

    /** 数据库文本类型 */
    public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };

    /** 数据库时间类型 */
    public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };

    /** 数据库数字类型 */
    public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
            "bit", "bigint", "float", "double", "decimal" };

    /** 页面不需要新增字段*/
    public static final String[] COLUMNNAME_NOT_INSERT = { ID, STATE, CREATE_BY, CREATE_TIME, DEL_FLAG ,UPDATE_TIME,UPDATE_BY };
    /** 页面不需要编辑字段 */
    public static final String[] COLUMNNAME_NOT_EDIT = { ID, CREATE_BY, CREATE_TIME, DEL_FLAG,UPDATE_TIME,UPDATE_BY  };
    /** 页面隐藏的列字段 */
    public static final String[] INVISIBLE_COLUMN_NAME = {ID, CREATE_BY, CREATE_TIME, UPDATE_BY,UPDATE_TIME};
    /** 页面不需要显示的列表字段 */
    public static final String[] COLUMNNAME_NOT_LIST = { DEL_FLAG };

    /** 页面不需要查询字段 */
    public static final String[] COLUMNNAME_NOT_QUERY = { ID, CREATE_BY, DEL_FLAG, UPDATE_BY,
            UPDATE_TIME, REMARK,WEIGHT };

    /** 基类中的查询字段 */
    public static final String SEARCH_VALUE = "searchValue";

    /** 查询自定义的参数对象 */
    public static final String PARAMS = "params";

    /** Entity基类字段 */
    public static final String[] BASE_ENTITY ;

    /** 不需要进行过滤的字段 */
    //public static final String[] NOT_FILTER ;

    /** Tree基类字段 */
    public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors" };

    /** 文本框 */
    public static final String HTML_INPUT = "input";

    /** number框*/
    public static final String HTML_INPUT_NUMBER = "inputNumber";

    /** 文本域 */
    public static final String HTML_TEXTAREA = "textarea";

    /** 下拉框 */
    public static final String HTML_SELECT = "select";

    /** 单选框 */
    public static final String HTML_RADIO = "radio";

    /** 复选框 */
    public static final String HTML_CHECKBOX = "checkbox";

    /** 日期控件 */
    public static final String HTML_DATETIME = "datetime";

    /** 上传控件 */
    public static final String HTML_UPLOAD = "upload";

    /** 富文本控件 */
    public static final String HTML_SUMMERNOTE = "summernote";

    /** 字符串类型 */
    public static final String TYPE_STRING = "String";

    /** 整型 */
    public static final String TYPE_INTEGER = "Integer";

    /** 长整型 */
    public static final String TYPE_LONG = "Long";

    /** 浮点型 */
    public static final String TYPE_DOUBLE = "Double";

    /** 高精度计算类型 */
    public static final String TYPE_BIGDECIMAL = "BigDecimal";

    /** 时间类型 */
    public static final String TYPE_DATE = "Date";

    /** 模糊查询 */
    public static final String QUERY_LIKE = "LIKE";

    /** 范围查询*/
    public static final String BETWEEN = "BETWEEN";

    /** 需要 */
    public static final String REQUIRE = "1";
    //属于基类对象的属性 但是标记为不是数据库字段 set
    public static Set DEFAULT_BASE_ENTITY_TABLE_FIELD_OF_NONEXISTENT_SET;
    /** 默认新增自动填充的字段*/
    public static final Map<String, Supplier<Object>> insertFillMap;
    /** 默认修改时自动填充的字段*/
    public static final Map<String,Supplier<Object>> updateFillMap;
    /** 数据库字段与属性字段映射  k数据库字段 v属性字段*/
    public static final Map<String,String> propetyFieldMap;
    /**数据库关键字*/
    public static final Set DEFAULT_KEYWORD_SET;
    /**entity基类字段 且默认表结构中需要有的字段*/
    public static final String [] DEFAULT_TABLE_FIELD;
    /**字典值与属性值的默认映射管理*/
    public static final Map<String,String> DEFAULT_FIELD_DICT_MAP;
    static{
        propetyFieldMap = new HashMap<>();
        propetyFieldMap.put(DEL_FLAG,"delFlag");
        propetyFieldMap.put(STATE,STATE);
        propetyFieldMap.put(CREATE_TIME,"createTime");
        propetyFieldMap.put(CREATE_BY,"createBy");
        propetyFieldMap.put(UPDATE_TIME,"updateTime");
        propetyFieldMap.put(UPDATE_BY,"updateBy");
        propetyFieldMap.put(REMARK,"remark");
        propetyFieldMap.put(WEIGHT,"weight");
        propetyFieldMap.put(ID,"id");

        DEFAULT_TABLE_FIELD = new String[]{propetyFieldMap.get(STATE),propetyFieldMap.get(CREATE_TIME),propetyFieldMap.get(UPDATE_TIME),propetyFieldMap.get(WEIGHT)};

        insertFillMap = new HashMap<>(3);
        updateFillMap = new HashMap<>(2);

        insertFillMap.put(propetyFieldMap.get(STATE), ()-> State.OK);
        insertFillMap.put(propetyFieldMap.get(CREATE_TIME), DateUtils::getNowDate);
        insertFillMap.put(propetyFieldMap.get(CREATE_BY),GenConstants::getUserName);

        updateFillMap.put(propetyFieldMap.get(UPDATE_TIME),DateUtils::getNowDate);
        updateFillMap.put(propetyFieldMap.get(UPDATE_BY),GenConstants::getUserName);

        DEFAULT_FIELD_DICT_MAP = new HashMap<>(1);
        DEFAULT_FIELD_DICT_MAP.put(propetyFieldMap.get(STATE),"data_normal_disable");

        BASE_ENTITY = new String[]{propetyFieldMap.get(STATE),propetyFieldMap.get(WEIGHT),propetyFieldMap.get(CREATE_BY),propetyFieldMap.get(CREATE_TIME),propetyFieldMap.get(UPDATE_BY),propetyFieldMap.get(UPDATE_TIME), propetyFieldMap.get(REMARK) };

        DEFAULT_BASE_ENTITY_TABLE_FIELD_OF_NONEXISTENT_SET = Stream.of(propetyFieldMap.get(CREATE_BY),propetyFieldMap.get(UPDATE_BY),propetyFieldMap.get(REMARK)).collect(Collectors.toSet());

        //NOT_FILTER = new String{ID,SEARCH_VALUE,PARAMS,propetyFieldMap.get(DEL_FLAG),propetyFieldMap.get(WEIGHT),propetyFieldMap.get(CREATE_BY),propetyFieldMap.get(CREATE_TIME),propetyFieldMap.get(UPDATE_BY),propetyFieldMap.get(UPDATE_TIME), propetyFieldMap.get(REMARK),"class"};

        DEFAULT_KEYWORD_SET = Stream.of("add","all","alter","analyze","and","as","asc","asensitive","before","between","bigint","binary","blob","both","by","call","cascade","case","change","char","character","check","collate","column","condition","connection","constraint","continue","convert","create","cross","current_date","current_time","current_timestamp","current_user","cursor","database","databases","day_hour","day_microsecond","day_minute","day_second","dec","decimal","declare","default","delayed","delete","desc","describe","deterministic","distinct","distinctrow","div","double","drop","dual","each","else","elseif","enclosed","escaped","exists","exit","explain","false","fetch","float","float4","float8","for","force","foreign","from","fulltext","goto","grant","group","having","high_priority","hour_microsecond","hour_minute","hour_second","if","ignore","in","index","infile","inner","inout","insensitive","insert","int","int1","int2","int3","int4","int8","integer","interval","into","is","iterate","join","key","keys","kill","label","leading","leave","left","like","limit","linear","lines","load","localtime","localtimestamp","lock","long","longblob","longtext","loop","low_priority","match","mediumblob","mediumint","mediumtext","middleint","minute_microsecond","minute_second","mod","modifies","natural","not","no_write_to_binlog","null","numeric","on","optimize","option","optionally","or","order","out","outer","outfile","precision","primary","procedure","purge","raid0","range","read","reads","real","references","regexp","release","rename","repeat","replace","require","restrict","return","revoke","right","rlike","schema","schemas","second_microsecond","select","sensitive","separator","set","show","smallint","spatial","specific","sql","sqlexception","sqlstate","sqlwarning","sql_big_result","sql_calc_found_rows","sql_small_result","ssl","starting","straight_join","table","terminated","then","tinyblob","tinyint","tinytext","to","trailing","trigger","true","undo","union","unique","unlock","unsigned","update","usage","use","using","utc_date","utc_time","utc_timestamp","values","varbinary","varchar","varcharacter","varying","when","where","while","with","write","x509","xor","year_month","zerofill")
                .collect(Collectors.toSet());
    }

    /**
     * 获取用户名称 如果有的话
     * @return
     */
    public static String getUserName(){
        SysUser sysUser = ShiroUtils.getSysUser();
        if(StringUtils.isNotNull(sysUser)){
            return sysUser.getUserName();
        }
        return null;
    }
}
